home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dviselect / binding.h < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-16  |  6.2 KB  |  195 lines

  1. /* C-TeX function and variable bindings */
  2.  
  3. /*
  4.  * Copyright (c) 1987 University of Maryland Department of Computer Science.
  5.  * All rights reserved.  Permission to copy for any purpose is hereby granted
  6.  * so long as this copyright notice remains intact.
  7.  */
  8.  
  9. #ifdef StringSizeof
  10. /*
  11.  * If StringSizeof is defined, we assume that (sizeof "string_const") is
  12.  * equal to (strlen("string_const") + 1); see the DefXXX macros below.
  13.  */
  14. #endif
  15.  
  16. /*
  17.  * Here are the various flags that can be in the b_flags field of a struct
  18.  * BoundName.
  19.  */
  20. #define BIsSpecial    1    /* a special int or dimen, or a font;
  21.                    assignments to these are always
  22.                    global */
  23. #define BIsOuter    2    /* \outer, may not appear in macro def'n */
  24. #define BIsLong        4    /* \long, may contain \outer s anyway */
  25. #define BIsUndef    8    /* not defined anymore - used when a def'n
  26.                    local to a group is destroyed by exiting
  27.                    the group */
  28.  
  29. /*
  30.  * SPECIAL
  31.  * 1. Integers:
  32.  *    \spacefactor \prevgraf \deadcycles \insertpenalties
  33.  * 2. Dimens:
  34.  *    \prevdepth \pagegoal \pagetotal \pagestretch \pagefilstretch
  35.  *    \pagefillstretch \pagefilllstretch \pageshrink \pagedepth
  36.  */
  37.  
  38. enum BindingKind {
  39.     ProcBound, VarBound, IntBound, DimenBound, CodeBound,
  40.     FontBound
  41. };
  42.  
  43. union BindUnion {
  44.     int    (*b_proc)();        /* iff ProcBound */
  45.     struct    node *b_var;        /* iff VarBound */
  46.     i32    *b_int;            /* iff IntBound */
  47.     scaled    *b_dimen;        /* iff DimenBound */
  48.     i32    b_code;            /* iff CodeBound */
  49.     struct    FontInfo *b_font;    /* iff FontBound */
  50. };
  51.  
  52. /*
  53.  * The basic entity of C-TeX is the `BoundName'.  It is either a wired-in
  54.  * procedure (e.g. \let, \def, \vskip) or variable (\hsize, \parskip), or a
  55.  * user-defined macro/variable/whatnot.  These are indistinguishable from
  56.  * one another (except that only wired procedures are ProcBound).
  57.  *
  58.  * There are also `CodeBound' things, which have no b_name and no b_flags.
  59.  * In fact, they are really BoundNameCodes, but they need similar treatment,
  60.  * so they get a similar structure.
  61.  */
  62. struct BoundName {
  63.     enum    BindingKind b_binding;    /* the kind of thing it is */
  64.     union    BindUnion b_bound;    /* the current binding */
  65.     struct    SavedVal *b_AfterGroupRst;
  66.                     /* The saved value for restoration
  67.                        after the current group.  This
  68.                        is a pointer into the current
  69.                        AfterGroupRst list. */
  70.     struct    string b_name;        /* the name of this thing */
  71.     int    b_flags;        /* various flags */
  72. };
  73.  
  74. /*
  75.  * \catcodes, \lccodes, etc are CodeBound, and are really arrays of these:
  76.  */
  77. struct BoundNameCode {
  78.     enum    BindingKind b_binding;
  79.     union    BindUnion b_bound;
  80.     struct    SavedVal *b_AfterGroupRst;
  81. };
  82.  
  83. /*
  84.  * Saved values (changes that are local to a group) are stored in a doubly
  85.  * linked list; this is so that constructs like
  86.  *    {\advance\count0 by1 \global\advance\count0 by1}
  87.  * can easily delete restorations that are no longer needed (having been
  88.  * overridden by a \global operation).  In other words, we never have
  89.  * any `save stack buildup'.  This requires the `spaghetti' below: a
  90.  * current group level (so if b_AfterGroupRst is set, we can tell whether
  91.  * the saved val is for this level) and moreover any inner saves for this
  92.  * BoundName.
  93.  *
  94.  * To illustrate what is going on, suppose that we have count1==0.  Now we
  95.  * begin group number 1, then 2.  Now we set count1 to 5, and since it has
  96.  * no AfterGroupRst we save the 0 at level 2.  Now we increment count1, and
  97.  * since it has an AfterGroupRst, we check the level.  It is 2; everything
  98.  * is fine, and count1 is set to 6.  Now we begin group 3, and again increment
  99.  * count1.  The level is 2, so we make a new SavedVal and set its level to
  100.  * 3.  (We now have count1==7, save==6 when exiting level 3, save==0 when
  101.  * exiting 2.)  Now the user does a \global\count1=42, so alas!, all those
  102.  * saved values are useless.  To get rid of them, we delete the current
  103.  * SavedVal, and its inner, and its inner's inner, and so forth, then clear
  104.  * the AfterGroupRst pointer.  Voila!  A global \count1, set to 42.
  105.  *
  106.  * Note that we save CodeBound changes here too.  Since CodeBound objects
  107.  * have no flags, some care is needed during restoration.
  108.  */
  109. struct SavedVal {
  110.     int    sv_level;        /* the level to which this belongs */
  111.     struct    SavedVal *sv_next;    /* linked list */
  112.     struct    SavedVal *sv_prev;    /* or more precisely, queue */
  113.     struct    SavedVal *sv_inner;    /* the inner saved value (from the
  114.                        previous group that saved this) */
  115.     union    BindUnion sv_val;    /* the saved value (note that saved
  116.                        values are always the same type
  117.                        as current values---i.e., types
  118.                        are fixed) */
  119.     struct    BoundName *sv_b;    /* the BoundName to which it belongs */
  120.     int    sv_flags;        /* the saved b_flags (if applicable) */
  121. };
  122.  
  123. struct    BoundName **NewNames;    /* during initialization, each internal
  124.                    BoundName is stashed in the table to
  125.                    which this points */
  126.  
  127. int    CurrentGroup;        /* the group level number of the current
  128.                    group; incremented for { and decremented
  129.                    for }, etc */
  130.  
  131. struct    SavedVal *AfterGroupRst;/* the current list for restoring locally
  132.                    modified BoundNames */
  133.  
  134. /*
  135.  * The following hackery will make the compiler complain in the event
  136.  * of a dropped semicolon, without making lint complain.
  137.  */
  138. #ifdef lint
  139. #define do_nothing    (void) rand()
  140. #else
  141. #define do_nothing    0
  142. #endif
  143.  
  144. /*
  145.  * Save a binding.
  146.  */
  147. #define SaveB(b) \
  148.     if ((b)->b_AfterGroupRst == NULL || \
  149.         (b)->b_AfterGroupRst->sv_level != CurrentGroup) \
  150.         DoSave(b); \
  151.     else \
  152.         do_nothing
  153.  
  154. /*
  155.  * Undo a save.
  156.  */
  157. #define UnSaveB(b) \
  158.     if ((b)->b_AfterGroupRst) \
  159.         DoUnsave(b); \
  160.     else \
  161.         do_nothing
  162.  
  163. #ifdef StringSizeof
  164. #define InitStrAndLen(str,cstr) (str.s_len = sizeof cstr-1, str.s_str = cstr)
  165. #else
  166. #define InitStrAndLen(str,cstr) (str.s_len = strlen(str.s_str = cstr))
  167. #endif
  168.  
  169. #define SetBFlags(f)    NewNames[-1].b_flags |= (f)
  170.  
  171. #define DefIntVar(addr, name) { \
  172.     static struct BoundName _b; \
  173.     InitStrAndLen(_b.b_name, name); \
  174.     _b.b_binding = IntBound; \
  175.     _b.b_bound.b_int = addr; \
  176.     *NewNames++ = &_b; \
  177. }
  178.  
  179. #define DefDimenVar(addr, name) { \
  180.     static struct BoundName _b; \
  181.     InitStrAndLen(_b.b_name, name); \
  182.     _b.b_binding = DimenBound; \
  183.     _b.b_bound.b_dimen = addr; \
  184.     *NewNames++ = &_b; \
  185. }
  186.  
  187. #define DefProc(name, proc, flags) { \
  188.     static struct BoundName _b; \
  189.     InitStrAndLen(_b.b_name, name); \
  190.     _b.b_binding = ProcBound; \
  191.     _b.b_bound.b_proc = proc; \
  192.     _b.b_bound.b_flags = flags; \
  193.     *NewNames++ = &_b; \
  194. }
  195.